package ch1.pool;

import java.sql.Connection;
import java.util.LinkedList;

/**
 * 类说明：wait notify做成的连接池
 */
public class DBPool {

    //链表，存放连接
    private static LinkedList<Connection> pool = new LinkedList<Connection>();

    /*限制了池的大小=20*/
    public DBPool(int initialSize) {
        if (initialSize > 0) {
            for (int i = 0; i < initialSize; i++) {
                pool.addLast(SqlConnectImpl.fetchConnection());
            }
        }
    }

    /**
     * 释放连接
     * <p>
     * 1.连接池加入一个连接 pool.addLast(connection)， 不需要判断是否满因为连接池有初始容量也是最大容量
     * 2.通知其他等待连接的线程
     */
    public void releaseConnection(Connection connection) {
        if (connection != null) {
            synchronized (pool) {
                pool.addLast(connection);
                //通知其他等待连接的线程
                pool.notifyAll();
            }
        }
    }

    /**
     * 获取连接
     * <p>
     * 1.连接池减去一个连接 pool.removeFirst()，需要判断不为空
     * 2.如果为空，等到
     */

    public Connection fetchConnection(long mills) throws InterruptedException {
        synchronized (pool) {
            //永不超时
            if (mills <= 0) {
                while (pool.isEmpty()) {
                    //如果池为空，需要等待被人释放再获取
                    pool.wait();
                }
                return pool.removeFirst();
            } else {
                /*超时时刻*/
                long future = System.currentTimeMillis() + mills;
                /*等待时长*/
                long remaining = mills;
                while (pool.isEmpty() && remaining > 0) {
                    pool.wait(remaining);
                    /*唤醒一次，重新计算等待时长*/
                    remaining = future - System.currentTimeMillis();
                }
                Connection connection = null;
                if (!pool.isEmpty()) {
                    connection = pool.removeFirst();
                }
                return connection;
            }
        }

    }
}
